package com.example.lib_ipc.service;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;

import androidx.annotation.Nullable;

import com.example.lib_ipc.UserBinderInterface;
import com.example.lib_ipc.bean.RequestBean;
import com.example.lib_ipc.bean.RequestParameter;
import com.example.lib_ipc.cache.CacheCenter;
import com.google.gson.Gson;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class UserServiceManager extends Service {
    //服务获取 实例化对象
    public static final int TYPE_GET = 1;
    //服务调用 调用对象方法
    public static final int TYPE_INVOKE = 2;

    private CacheCenter mCacheCenter = CacheCenter.getInstance();

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return new UserBinderInterface.Stub() {
            @Override
            public String request(String request) throws RemoteException {
                //当前主进程
                //获取从B进程传递过来的Json字符串
                RequestBean requestBean = new Gson().fromJson(request, RequestBean.class);
                switch (requestBean.getType()) {
                    case TYPE_GET:
                        Method method = mCacheCenter.getMethod(requestBean);
                        if (method != null) {
                            try {
                                Object[] parameters = makeParameterObject(requestBean);
                                Object obj = method.invoke(null, parameters);
                                if (obj != null) {
                                    //保存使用的对象
                                    mCacheCenter.putObject(requestBean.getClassName(), obj);
                                }
                            } catch (IllegalAccessException | InvocationTargetException e) {
                                e.printStackTrace();
                            }
                        }
                        break;
                    case TYPE_INVOKE:
                        Object object = mCacheCenter.getObject(requestBean.getClassName());
                        Method tempMethod = mCacheCenter.getMethod(requestBean);
                        Object[] mParameterObject = makeParameterObject(requestBean);

                        try {
                            Object result = tempMethod.invoke(object, mParameterObject);
                            if (result != null){
                                return new Gson().toJson(result);
                            }
                        } catch (IllegalAccessException | InvocationTargetException e) {
                            e.printStackTrace();
                        }
                        break;
                    default:
                        break;
                }
                return null;
            }
        };
    }

    /**
     * 还原从B进程传递过去Object... parameters
     * public <T> T getInstance(Class<T> clazz, Object... parameters)
     *
     * @param requestBean
     * @return
     */
    private Object[] makeParameterObject(RequestBean requestBean) {
        Object[] mParameters = null;
        RequestParameter[] requestParameters = requestBean.getRequestParameters();
        if (requestParameters != null && requestParameters.length > 0) {
            mParameters = new Object[requestParameters.length];
            for (int i = 0; i < requestParameters.length; i++) {
                RequestParameter requestParameter = requestParameters[i];
                Class<?> clazz = mCacheCenter.getClassType(requestParameter.getParameterClassName());
                mParameters[i] = new Gson().fromJson(requestParameter.getParameterValue(), clazz);
            }
        } else {
            mParameters = new Object[0];
        }

        return mParameters;
    }
}
